package com.eastandroid.zoom;

import java.util.ArrayList;

import com.eastandroid.zoom.GestureBase.OnEventDebugListener;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class ZoomStateView extends View implements OnEventDebugListener {
	private static final String TAG = "ZoomStateView";
	private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);

	private static class EventInfo {
		public EventInfo(float x, float y, int pointerId) {
			this.x = x;
			this.y = y;
			this.id = pointerId;
		}

		float x;
		float y;
		int id;
		public int color = Color.YELLOW;
	}

	private int mW;
	private int mH;
	private Paint mPaintLine;
	private float radius = 100f;

	private RectF mSrcRect = new RectF();
	private RectF mDstRect = new RectF();
	private RectF mOrgRect = new RectF();
	private RectF mViewRect = new RectF();
	private float[] mSrc = new float[4];
	private float[] mDst = new float[4];

	ArrayList<EventInfo> eventInfos = new ArrayList<EventInfo>();
	ArrayList<EventInfo> eventDrawInfos = new ArrayList<EventInfo>();

	PointF mCenterPoint = new PointF();

	public ZoomStateView(Context context) {
		super(context);
		create(context);
	}

	public ZoomStateView(Context context, AttributeSet attrs) {
		super(context, attrs);
		create(context);
	}

	public ZoomStateView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		create(context);
	}

	private void create(Context context) {
		// Log.e(TAG, ""+"at "+new Exception().getStackTrace()[0].toString());
		mPaintLine = new Paint(Paint.ANTI_ALIAS_FLAG);
		mPaintLine.setColor(Color.RED);
		mPaintLine.setStyle(Paint.Style.STROKE);
	}

	@Override
	protected void onDraw(Canvas canvas) {

//		drawPointReleave(canvas, eventInfos);
//		drawPointEffect(canvas, eventInfos);
//		drawPointEffect(canvas, eventDrawInfos);

//		mZoomState._dump(mViewRect, mOrgRect, mSrcRect, mDstRect, mSrc, mDst);
//
//		// ì›�ë³¸ìœ„ì¹˜
		drawRect(canvas, mOrgRect, Color.GREEN, 2);
//
//		// ë³€í˜•ìœ„ì¹˜
//		{
//			RectF dst = new RectF();
//			mZoomState.getZoomRect(dst);
//			drawRect(canvas, dst, Color.YELLOW, 5);
//		}
//
//		// í�¬ê¸° ì¡°ì •ìœ„ì¹˜
//		{
//			RectF dst = new RectF();
//			mZoomState.getMinSize(dst);
//			drawRect(canvas, dst, Color.CYAN, 2);
//		}
//		// ìœ„ì¹˜ ì¡°ì •ìœ„ì¹˜
//		{
//			RectF dst = new RectF();
//			mZoomState.getAdjPosition(dst);
//			drawRect(canvas, dst, Color.MAGENTA, 3);
//		}

	}

	private void drawRect(Canvas canvas, RectF rect, int color, int width) {
		mPaintLine.setStrokeWidth(width);
		mPaintLine.setColor(color);
		canvas.drawRect(rect, mPaintLine);
		canvas.drawLine(rect.left, rect.top, rect.right, rect.bottom, mPaintLine);
		canvas.drawLine(rect.left, rect.bottom, rect.right, rect.top, mPaintLine);
	}

	private void drawPointEffect(Canvas canvas, ArrayList<EventInfo> eventInfos) {
		for (EventInfo eventInfo : eventInfos) {
			drawPointEffect(canvas, eventInfo);
		}
	}

	private void drawPointEffect(Canvas canvas, EventInfo eventInfo) {
		final float x = eventInfo.x;
		final float y = eventInfo.y;
		final int color = eventInfo.color;

		drawLineX(canvas, Color.RED, y);
		drawLineY(canvas, Color.RED, x);
		mPaintLine.setColor(color);
		mPaintLine.setTextSize(40);
		mPaintLine.setTextAlign(Paint.Align.RIGHT);
		canvas.drawCircle(x, y, radius, mPaintLine);
		canvas.drawText(Integer.toString(eventInfo.id), x + radius, y - radius, mPaintLine);
	}

	private void drawPointReleave(Canvas canvas, ArrayList<EventInfo> eventInfos) {
		if (eventInfos.size() >= 2)
			drawPointReleave(canvas, new PointF(eventInfos.get(0).x, eventInfos.get(0).y), new PointF(eventInfos.get(1).x, eventInfos.get(1).y));
	}

	private void drawPointReleave(Canvas canvas, PointF p1, PointF p2) {
		// Log.e(TAG, ""+"at "+new Exception().getStackTrace()[0].toString());
		mPaintLine.setStrokeWidth(1);
		mPaintLine.setColor(Color.BLUE);
		canvas.drawLine(p1.x, p1.y, p2.x, p2.y, mPaintLine);
		canvas.drawLine(p1.x, p2.y, p2.x, p1.y, mPaintLine);

		centerPoint(mCenterPoint, p1, p2);
		float r = distance(p1, p2) / 2f;
		canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, distance(p1, p2) / 2, mPaintLine);
		canvas.drawRect(mCenterPoint.x - r, mCenterPoint.y - r, mCenterPoint.x + r, mCenterPoint.y + r, mPaintLine);
	}

	public void drawLineX(Canvas canvas, int color, float y) {
		canvas.save();
		canvas.translate(0, y);
		mPaintLine.setColor(color);
		canvas.drawLine(0, 0, mW, 0, mPaintLine);
		canvas.restore();
	}

	public void drawLineY(Canvas canvas, int color, float x) {
		canvas.save();
		canvas.translate(x, 0);
		mPaintLine.setColor(color);
		canvas.drawLine(0, 0, 0, mH, mPaintLine);
		canvas.restore();
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		Log.e(TAG, "" + "at " + new Exception().getStackTrace()[0].toString());
		mW = w;
		mH = h;
		super.onSizeChanged(w, h, oldw, oldh);
	}

	private float distance(PointF p1, PointF p2) {
		float x = p1.x - p2.x;
		float y = p1.y - p2.y;
		return FloatMath.sqrt(x * x + y * y);
	}

	private void centerPoint(PointF p, PointF p1, PointF p2) {
		float x = p1.x + p2.x;
		float y = p1.y + p2.y;
		p.set(x / 2, y / 2);
	}

	private ZoomState mZoomState;

	public void setZoomState(ZoomState zoomState) {
		mZoomState = zoomState;
	}

	@Override
	public void onEventDebugListener(GestureBase gesture, MotionEvent event) {
		// Log.e(TAG, ""+"at "+new Exception().getStackTrace()[0].toString());
		eventInfos.clear();
		if (event == null)
			return;

		int count = event.getPointerCount();
		for (int i = 0; i < count; i++) {
			eventInfos.add(new EventInfo(event.getX(i), event.getY(i), event.getPointerId(i)));
		}
		if (eventInfos.size() > 0)
			eventInfos.get(0).color = Color.WHITE;
		if (eventInfos.size() > 1)
			eventInfos.get(1).color = Color.LTGRAY;

		eventDrawInfos.clear();
		if (gesture instanceof GestureDraw) {
			Matrix matrix = new Matrix();
			mZoomState.getMatrix().invert(matrix);

			for (int i = 0; i < count; i++) {
				float[] src = new float[] { event.getX(i), event.getY(i) };
				float[] dst = new float[2];
				matrix.mapPoints(dst, src);
				eventDrawInfos.add(new EventInfo(dst[0], dst[1], event.getPointerId(i)));
			}
		}
		invalidate();

	}

}
